/*
 * @Author: wangyongcun
 * @Date: 2023-09-06 10:50:08
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2024-05-28 22:17:40
 * @Description: 登录相关
 */
import jwt from "jsonwebtoken";
const { valiteToken, allowedPath, secretKey, expiresIn } =
  globalConfig.authConfig;
const jwtexpiresIn = `${expiresIn / 24}d`;
class Login {
  constructor() {}
  /**
   * @description: 登录
   * @param {*} ctx
   * @return {*}
   */
  async login(ctx) {
    try {
      // 获取参数
      let { phone, password } = ctx.request.body;
      // 非空校验
      if (!phone || !password) {
        ctx.body = resUtil.error("账号或者密码不能为空");
        return;
      }
      // 从数据库获取用户信息
      let sql = `SELECT * FROM user WHERE phone='${phone}' AND password='${password}'`;
      let { status, results } = await db(sql);
      // 查询结果
      if (status != 200) throw "数据查询失败";
      if (results.length == 0) throw "账号或者密码错误";
      let Content = results[0];
      let menuList = Content.menuList;
      Content.menuText = "--";
      if (menuList.length) {
        menuList = JSON.parse(menuList);
        menuList = await this.queryMenuList({
          path: menuList,
        });
        Content.menuList = menuList;
        Content.menuText = menuList.map((menu) => menu.title).join("、");
      }

      // 设置token
      this.createToken(ctx, Content.id);
      // 返回结果
      ctx.body = resUtil.success({
        Content,
      });
    } catch (err) {
      log.error(`Login-login-登录失败：${err}`);
      ctx.body = resUtil.error(err);
    }
  }
  /**
   * @description: 退出登录
   * @param {*} ctx
   * @return {*}
   */
  loginOut(ctx) {
    try {
      // 清空cookie
      ctx.cookies.set("token", "", {
        maxAge: -1, // 设置为过去的时间
        expires: new Date(1970, 0, 1), // 同上，设置为Unix纪元时间
      });
      ctx.body = resUtil.success("已退出登录");
    } catch (err) {
      log.error(`Login-loginOut:${err}`);
      ctx.body = resUtil.error("退出登录失败");
    }
  }
  /**
   * @description: 生成token令牌
   * @param {*} userId
   * @return {*}
   */
  createToken(ctx, userId) {
    try {
      const token = jwt.sign({ userId }, secretKey, {
        expiresIn: jwtexpiresIn,
      });
      ctx.cookies.set("token", token, {
        maxAge: expiresIn,
        httpOnly: false,
        overwrite: true,
      });
    } catch (err) {
      log.error(`Login-createToken:${err}`);
    }
  }
  /**
   * @description: token校验以及续期
   * @return {*}
   */
  async checkToken(ctx, next) {
    try {
      // 不校验token 或者白名单里的接口直接放行
      if (!valiteToken || allowedPath.includes(ctx.path)) {
        return next();
      }
      const token = ctx.cookies.get("token");
      const decoded = jwt.verify(token, secretKey); // 解码token验证有效性
      this.createToken(ctx, decoded.userId);
      return next();
    } catch (err) {
      log.error(`Login-checkToken:${err}`);
      ctx.body = resUtil.error({
        Content: "token不存在或者已过期",
        Code: 401,
      });
    }
  }
  /**
   * @description: 查询菜单列表
   * @param {*} ctx
   * @return {*}
   */
  async queryMenuList(params = {}) {
    try {
      let keys = Object.keys(params);
      let sqlParams = ``;
      keys.forEach((key, index) => {
        let val = params[key];
        if (Array.isArray(val)) {
          sqlParams += `${key} IN ('${val.join("','")}')`;
        } else {
          sqlParams += `${key}='${params[key]}`;
        }
        sqlParams += `${index == keys.length - 1 ? "" : " AND "}`;
      });
      let sql = `SELECT * FROM menu_dic WHERE ${sqlParams} ORDER BY sort`;
      let { status, results } = await db(sql);
      if (status != 200) throw "查询菜单失败";
      return results || [];
    } catch (err) {
      log.error(`Login-queryMenuList：${err}`);
      return [];
    }
  }
}

export default new Login();
